/*
 * #%L
 * SwiftUICommonUtilities
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2011 - 2012 Linkwithweb
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */
package com.linkwithweb.products.swiftui.spring.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
import org.springframework.jdbc.core.RowMapper;

/**
 * This Class Create Table MetaData in First Call and then returns rowMap
 * 
 * @author ashwin
 * 
 */
public class TableComponentRowMapper implements RowMapper {
	private static final transient Log logger = LogFactory
			.getLog(TableComponentRowMapper.class);
	private String entityName = null;

	private boolean loadData = true;
	PeriodFormatter stringPeriodFormatter = new PeriodFormatterBuilder()
			.appendYears().printZeroNever().appendSuffix(" year", " years")
			.appendSeparator(" and ").appendMonths().printZeroNever()
			.appendSuffix(" month", " months").appendDays().printZeroNever()
			.appendSuffix(" Day", " Days").appendHours().printZeroNever()
			.appendSuffix(" Hour", " Hours").appendMinutes().printZeroNever()
			.appendSuffix(" Minute", " Minutes").appendSeconds()
			.printZeroNever().appendSuffix(" Second", " Seconds")
			.printZeroNever().toFormatter();
	PeriodFormatter yearPeriodFormatter = new PeriodFormatterBuilder()
			.appendYears().printZeroAlways().toFormatter();

	long startIndex = 0;
	long endIndex = 500;

	/**
	 * @return the loadData
	 */
	public boolean isLoadData() {
		return loadData;
	}

	/**
	 * @param loadData
	 *            the loadData to set
	 */
	public void setLoadData(boolean loadData) {
		this.loadData = loadData;
	}

	public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
		try {
			int columnCount = rs.getMetaData().getColumnCount();

			List<MapObject> rowList = new ArrayList<MapObject>();
			Map<String, MapObject> rowMap = new HashMap<String, MapObject>();

			if (!loadData) {
				return rowList;
			}

			for (int i = 1; i <= columnCount; i++) {
				MapObject mapObject = new MapObject();
				mapObject.setKey(rs.getMetaData().getColumnName(i));
				mapObject.setRowNum(rowNum);

				if(StringUtils.equalsIgnoreCase(mapObject.getKey(), "RowNumber")){
					continue;
				}
				
				mapObject.setColumnType(rs.getMetaData().getColumnTypeName(i));

				Object actualValue = null;

				try {
					actualValue = rs.getObject(i);
				} catch (Exception e) {
					actualValue = rs.getString(i);
				}

				String value = "";
				if (actualValue != null) {
					/*value = StringEscapeUtils
							.escapeHtml(actualValue.toString());*/
					value = StringEscapeUtils.escapeXml(new String(actualValue.toString().getBytes("UTF-8")));
					/*.xmlEncodeString(new String(actualValue.toString().getBytes("UTF-8")));*/
				}

				mapObject.setValue(value);
				mapObject.setActualValue(actualValue);
				rowMap.put(mapObject.getKey(), mapObject);
				rowList.add(mapObject);
			}

			return getReturnObject(rowMap, rowList);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;

	}

	/**
	 * @param rowMap
	 * @param rowList
	 * @return
	 */
	protected Object getReturnObject(Map<String, MapObject> rowMap,
			List<MapObject> rowList) {
		return rowList;
	}

	/**
	 * @return the entityName
	 */
	public String getEntityName() {
		return entityName;
	}

	/**
	 * @param entityName
	 *            the entityName to set
	 */
	public void setEntityName(String entityName) {
		this.entityName = entityName;
	}

	/**
	 * @return the startIndex
	 */
	public long getStartIndex() {
		return startIndex;
	}

	/**
	 * @param startIndex
	 *            the startIndex to set
	 */
	public void setStartIndex(long startIndex) {
		this.startIndex = startIndex;
	}

	/**
	 * @return the endIndex
	 */
	public long getEndIndex() {
		return endIndex;
	}

	/**
	 * @param endIndex
	 *            the endIndex to set
	 */
	public void setEndIndex(long endIndex) {
		this.endIndex = endIndex;
	}

}